package com.example.tcpmaster;


import android.util.Log;

import com.example.tcpmaster.interfaces.OnTcpClientStateListener;

import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;

/**
 * Created by lianxiang on 2017/9/6.
 */

public abstract class TcpClient implements Runnable, OnTcpClientStateListener {
    private boolean connected = false;
    private AbsSocketTransceiver transceiver;
    private static final String TAG = "TcpClient";
    private TcpConnectOptions tcpConnectOptions;

    public TcpClient(TcpConnectOptions tcpConnectOptions) {
        this.tcpConnectOptions = tcpConnectOptions;
    }

    public void connect() {
        new Thread(this, TAG).start();
    }

    Socket socket;

    @Override
    public void run() {
        try {
            socket = new Socket();

            TcpClient.this.onConnecting();
            socket.connect(new InetSocketAddress(tcpConnectOptions.getHostIP(), tcpConnectOptions.getPort()), tcpConnectOptions.getTimeOut()); //连接请求超时时间10s
            transceiver = getSocketTransceiver(this, socket);
            transceiver.setOnSocketTransceiverStateListener(new AbsSocketTransceiver.OnSocketTransceiverStateListener() {
                @Override
                public void onReceive(String data) {
                    TcpClient.this.onReceive(data);
                }

                @Override
                public void onDisconnect() {
                    connected = false;

                    TcpClient.this.onDisconnect();
                }

                @Override
                public void onException(Exception e) {
                    TcpClient.this.onException(e);
                }

                @Override
                public void onRequestTimeOut() {
                    Log.e("TAG", "==onRequestTimeOut==1===");
                    TcpClient.this.onRequestTimeOut();
                }
            });
            transceiver.start();
            connected = true;
            this.onConnectted();
        } catch (Exception e) {
            String failStr = "连接失败";
            int code = TcpSocketCode.SOCKET_FAILED;
            e.printStackTrace();
            if (e instanceof SocketTimeoutException) {
                failStr = "连接超时了！！！";
                code = TcpSocketCode.SOCKET_TIMEOUT;
            }
            this.onConnectFailed(code, failStr);
        }
    }

    /**
     * 断开连接
     * <p>
     * 连接断开，回调{@code onDisconnect()}
     */
    public void disconnect() {
        if (transceiver != null) {
            transceiver.stop();
            transceiver = null;

        }
    }

    /**
     * 判断是否连接
     *
     * @return
     */
    public boolean isConnected() {
        return connected;
    }

    public AbsSocketTransceiver getTransceiver() {
        return transceiver;
    }


    public abstract AbsSocketTransceiver getSocketTransceiver(TcpClient tcpClient, Socket socket);

}
